package eval;

import network.Device;
import network.Network;
import network.Rule;
import networkLoader.FBNetwork;
import partition.SubspacePartition;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class EarlyDetectionEval {
    public static int sumClosed = 0;
    public static long sumEDTime = 0;
    public static int sumProcessedRules = 0;

    public static void main(String[] args) throws InterruptedException {
        int nRulesPerSec = 1000000;
        int nSubspaces = 32;
        double prob = (double)1/100;
        if (args.length >= 1) {
            nRulesPerSec = Integer.parseInt(args[0]);
        }
        if (args.length >= 2) {
            nSubspaces = Integer.parseInt(args[1]);
        }
        if (args.length >= 3) {
            prob = Double.parseDouble(args[2])/100;
        }
        Network network = FBNetwork.getNetwork();
        for (Device device : network.getAllDevices()) device.uid = Device.cnt++;

        for (int i = 0; i < 1; i++) {
            run(network, nRulesPerSec, (int) (nSubspaces * Math.pow(2, i)), prob);
//            TimeUnit.SECONDS.sleep(70);
            System.gc();
        }

//        System.out.println("#avg Closed: " + (sumClosed / 5));
//        System.out.println("#avg Rules: " + (sumProcessedRules / 5));
//        System.out.println("#avg EDTime: " + (sumEDTime / 5));
    }

    private static void run(Network network, int nRulesPerSec, int nSubspaces, double prob) {

        for (Rule rule : network.getInitialRules()) {
            if (Math.random() < prob) {
                rule.setRandomOutPort();
            }
        }

        BlockingQueue<Rule> blockingQueue = new LinkedBlockingQueue<>();
        EventEmiter eventEmiter = new EventEmiter(network, blockingQueue, nRulesPerSec);
        HashMap<Long, SubspacePartition> idToSubspace = new HashMap<>();
        for (int i = 0; i < nSubspaces; i++) {
            SubspacePartition subspacePartition = new SubspacePartition(network, null, false, true);
            new Thread(subspacePartition).start();
            idToSubspace.put((long) i, subspacePartition);
        }

        Dispatcher dispatcher = new Dispatcher(blockingQueue, idToSubspace);
        new Thread(dispatcher).start();
        new Thread(eventEmiter).start();
    }
}